/* Copyright (C) 1999-2004 by Peter Eastman

   This program is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation; either version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but WITHOUT ANY 
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
   PARTICULAR PURPOSE.  See the GNU General Public License for more details. */

package artofillusion;

import artofillusion.animation.*;
import artofillusion.math.*;
import artofillusion.object.*;
import artofillusion.ui.*;
import buoy.event.*;
import java.awt.*;

/** CreateSphereTool is an EditingTool used for creating Sphere objects. */

public class CreateSphereTool extends EditingTool
{
  static Image icon, selectedIcon;
  static int counter = 1;
  boolean shiftDown;
  Point clickPoint;
  
  public CreateSphereTool(EditingWindow fr)
  {
    super(fr);
    icon = loadImage("sphere.gif");
    selectedIcon = loadImage("selected/sphere.gif");
  }

  public void activate()
  {
    super.activate();
    theWindow.setHelpText(Translate.text("createSphereTool.helpText"));
  }

  public int whichClicks()
  {
    return ALL_CLICKS;
  }

  public Image getIcon()
  {
    return icon;
  }

  public Image getSelectedIcon()
  {
    return selectedIcon;
  }

  public String getToolTipText()
  {
    return Translate.text("createSphereTool.tipText");
  }

  public void mousePressed(WidgetMouseEvent e, ViewerCanvas view)
  {
    clickPoint = e.getPoint();
    shiftDown = e.isShiftDown();
    ((SceneViewer) view).beginDraggingBox(clickPoint, shiftDown);
  }
  
  public void mouseReleased(WidgetMouseEvent e, ViewerCanvas view)
  {
    Scene theScene = ((LayoutWindow) theWindow).getScene();
    Camera cam = view.getCamera();
    Point dragPoint = e.getPoint();
    Vec3 v1, v2, v3, orig, xdir, ydir, zdir;
    double xsize, ysize, zsize;
    
    if (shiftDown)
      {
	if (Math.abs(dragPoint.x-clickPoint.x) > Math.abs(dragPoint.y-clickPoint.y))
	  {
	    if (dragPoint.y < clickPoint.y)
	      dragPoint.y = clickPoint.y - Math.abs(dragPoint.x-clickPoint.x);
	    else
	      dragPoint.y = clickPoint.y + Math.abs(dragPoint.x-clickPoint.x);
	  }
	else
	  {
	    if (dragPoint.x < clickPoint.x)
	      dragPoint.x = clickPoint.x - Math.abs(dragPoint.y-clickPoint.y);
	    else
	      dragPoint.x = clickPoint.x + Math.abs(dragPoint.y-clickPoint.y);
	  }
      }
    if (dragPoint.x == clickPoint.x || dragPoint.y == clickPoint.y)
      {
	Graphics g = view.getComponent().getGraphics();
	view.drawImage(g);
	g.dispose();
	return;
      }
    v1 = cam.convertScreenToWorld(clickPoint, ModellingApp.DIST_TO_SCREEN);
    v2 = cam.convertScreenToWorld(new Point(dragPoint.x, clickPoint.y), ModellingApp.DIST_TO_SCREEN);
    v3 = cam.convertScreenToWorld(dragPoint, ModellingApp.DIST_TO_SCREEN);
    orig = v1.plus(v3).times(0.5);
    if (dragPoint.x < clickPoint.x)
      xdir = v1.minus(v2);
    else
      xdir = v2.minus(v1);
    if (dragPoint.y < clickPoint.y)
      ydir = v3.minus(v2);
    else
      ydir = v2.minus(v3);
    xsize = xdir.length();
    ysize = ydir.length();
    xdir = xdir.times(1.0/xsize);
    ydir = ydir.times(1.0/ysize);
    zdir = xdir.cross(ydir);
    zsize = Math.min(xsize, ysize);
    Sphere obj = new Sphere(xsize/2.0, ysize/2.0, zsize/2.0);
    ObjectInfo info = new ObjectInfo(obj, new CoordinateSystem(orig, zdir, ydir), "Sphere "+(counter++));
    info.addTrack(new PositionTrack(info), 0);
    info.addTrack(new RotationTrack(info), 1);
    UndoRecord undo = new UndoRecord(theWindow, false);
    undo.addCommandAtBeginning(UndoRecord.SET_SCENE_SELECTION, new Object [] {theScene.getSelection()});
    ((LayoutWindow) theWindow).addObject(info, undo);
    theWindow.setUndoRecord(undo);
    ((LayoutWindow) theWindow).setSelection(theScene.getNumObjects()-1);
    theWindow.updateImage();
  }
}